home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
a86v302b.arc
/
12COMPAT.DOC
< prev
next >
Wrap
Text File
|
1987-04-08
|
10KB
|
192 lines
CHAPTER 12 COMPATIBILITY WITH OTHER ASSEMBLERS 12-1
I gave heavy priority to compatibility when I designed A86; a
priority just a shade behind the higher priorities of
reliability, speed, convenience, and power. For those of you who
feel that "close, but incompatible" is like saying "a little bit
pregnant", I'm sorry to report that A86 will not assemble all
Intel/IBM/MSDOS programs, unmodified. But I do think that a vast
majority of programs can, with a surprisingly little amount of
massaging, be made to assemble under A86. Furthermore, the
massaging can be done in such a way as to make the programs still
acceptable to that old, behemoth assembler.
Version 3.00 of A86 has many compatibility features not present
on earlier versions. Among the features added since A86 was
first released are: more general forward references, double-
quotes for strings, "=" as a synonym for EQU, the RADIX
directive, and the COMMENT directive. If you tried feeding an
old source file to a previous A86 and were dismayed by the number
of error messages you got, try again: things might be more
manageable now.
Conversion of Intel/IBM/MSDOS programs to A86
Following is a list of the things you should watch out for when
converting from Intel/IBM to A86:
1. If your program does not fit into 64K, with all the segment
registers pointing to the same value, then there may be
instructions in the program for which the old assembler
generates segment-override prefixes "behind your back". You
will need to find such references, and generate explicit
overrides for them. If there are data-tables within the
program itself, a CS-override is needed. If there are data-
structures in the stack segment not accessed via a BP-index,
an SS-override is needed. If ES points to its own segment,
then an ES-override is needed for accesses (other than STOS
and MOVS destinations) to that segment.
If you want to remain compatible with the old assembler, then
you code the overrides by placing the segment register name,
with a colon, before the memory-access operand in the
instruction. If you do not need further compatibility, you
can place the segment register name before the instruction
mnemonic. For example:
MOV AL,CS:TABLE[SI] ; if you want compatibility do it this way
CS MOV AL,TABLE[SI] ; if not you can do it this way
2. A86 is a bit more restrictive with respect to forward-
references than IBM's assembler, but not as much as it used to
be. You'll probably need to resolve just a few ambiguous
references by appending " B" or " W" to the forward-reference
name.
12-2
3. A86 has the feature, not seen in Intel/IBM, that the default
base for numbers with leading digit 0 is hexadecimal, not
decimal. This means that you must remove any leading zeroes
from decimal numbers in your old programs. Note that all
constants other than those without leading zeroes and without
trailing base-specifiers are handled identically by A86 and by
Intel/IBM. The ONLY thing you need to worry about is decimal
numbers with leading zeroes. Example: the old code line MOV
AX,00100, meaning decimal 100, should be recoded MOV AX,100,
without the leading zeroes.
Alternatively, I have added the RADIX command, for
compatibility with the .RADIX command of IBM's assembler. If
the program has a .RADIX command at the top of it, then my
assembler will handle constants identically to the IBM
assembler; if it does not, you can add a .RADIX 10 to the top
of the program, for complete compatibility.
For even greater convenience, I have added the +D switch,
which you can put into your A86 environment variable, to
achieve decimal functionality without a RADIX 10 command.
4. A86's macro definition language is different than Intel/IBM's.
Most macros can be translated by replacing the named
parameters of the old macros with the dedicated names #n of
the A86 macro language; and by replacing ENDM with #EM. To
retain compatibility, you isolate the old macro definitions in
an INCLUDE file (A86 will ignore the INCLUDE directive), and
isolate the A86 macro definitions in a separate file, not used
in an Intel/IBM assembly of the program.
5. A86 does not support a couple of the more exotic features of
Intel/IBM assembly language: the RECORD directive and its
associated operators WIDTH and MASK; and the usage of angle-
brackets to initialize structure-records. These features
would have added much complication to the internal structure
of symbol tables in A86; degrading the speed and the
reliability of the assembler. I felt that their use was
sufficiently rare that it was not worth including them for
compatibility. I would like to hear some feedback on this.
Does anybody out there use these features heavily? Will they
be missed in A86?
If your old program does use these features, you will have to
re-work the areas that use them. Macros can be used to
duplicate the record and structure initializations. Explicit
symbol declarations can replace the usage of the WIDTH and
MASK operators.
12-3
Compatibility-symbols recognized by A86
A86 has been programmed to ignore a variety of lines that have
meaning to Intel/IBM/MSDOS assemblers; but which do nothing for
A86. These include lines beginning with a period (except .RADIX,
which is acted upon), percent sign, or dollar sign; and lines
beginning with ASSUME, INCLUDE, PAGE, SUBTTL, and TITLE. If you
are porting your program to A86, and you wish to retain the
option of returning to the other assembler, you may leave those
lines in your program. If you decide to stay with A86, you can
remove those lines at your leisure.
In addition, there is a class of symbols now recognized by A86 in
its .OBJ mode, but still ignored in .COM mode. This includes
NAME, END, and PUBLIC.
Conversion of A86 Programs to Intel/IBM/MSDOS
I consider this section a bit of a blasphemy, since it's a little
silly to port programs from a superior assembler, to run on an
inferior one. However, I myself have been motivated to do so
upon occasion, when programming for a client not familiar with
A86; or whose computer doesn't run A86; who therefore wants the
final version to assemble on Intel's assembler. Since my
assembler/debugger environment is so vastly superior to any other
environment, I develop the program using my assembler, and port
it to the client's environment at the end.
The main key to success in following the above scenarios is to
exercise supreme will power, and not use any of the wonderful
language features that exist on A86, but not on the Intel/IBM
assembler. This is often not easy; and I have devised some
methods for porting my features to Intel/IBM assemblers:
1. I hate giving long sequences of PUSHes and POPs on separate
lines. If the program is to be ported to a lesser assembler,
then I put the following lines into a file that only A86 will
see:
PUSH2 EQU PUSH
PUSH3 EQU PUSH
POP2 EQU POP
POP3 EQU POP
I define macros PUSH2, PUSH3, POP2, POP3 for the lesser
assembler, that PUSH or POP the appropriate number of
operands. Then, everywhere in the program where I would
ordinarily use A86's multiple PUSH/POP feature, I use one or
more of the PUSHn/POPn mnemonics instead.
2. I refrain from using the feature of A86 whereby constants with
a leading zero are default-hexadecimal. All my hex constants
end with H.
12-4
3. I will usually go ahead and use my local labels L0 through L9;
then at the last minute convert them to a long sequence of
labels in sequence: Z100, Z101, Z102, etc. I take care to
remove all the ">" forward-reference specifiers when I make
the conversion. The "Z" is used to isolate the local labels
at the end of the lesser assembler's symbol-table listing.
This improves the quality of the final program so much that it
is worth the extra effort needed to convert L0--L9's to Z100-
Zxxx's.
4. I will place declarations B EQU DS:BYTE PTR 0 and W EQU
DS:WORD PTR 0 at the top of the program. Recall that A86 has
a "duplicate definition" feature whereby you can EQU an
already-existing symbol, as long as it is equated to the value
it already has. This feature extends to the built in symbols
B and W, so A86 will look at those equates and essentially
ignore them. On the old assembler, the effect of the
declarations is to add A86's notation to the old language.
Example:
B EQU DS:BYTE PTR 0
W EQU DS:WORD PTR 0
MOV AX,W[0100] ; replaces MOV AX, DS:WORD PTR 0100
MOV AL,B[BX] ; replaces MOV AL, DS:BYTE PTR [BX]
Note that I've just given you a tip that means even if you
don't choose to use A86, you'll never have to use BYTE PTR or
WORD PTR again! Now don't you just hate BYTE PTR and WORD
PTR? Isn't the tip alone worth sending me at least $5 for?